// EventListener.ts
// 通用观察者接口
interface EventListener {
    update(eventType: string, file: string): void;
}

// EmailNotificationListener.ts
// 收到通知后发送邮件
class EmailNotificationListener implements EventListener {
    private email: string;

    constructor(email: string) {
        this.email = email;
    }

    update(eventType: string, file: string): void {
        console.log(`Email to ${this.email}: Someone has performed ${eventType} operation with the following file: ${file}`);
    }
}

// LogOpenListener.ts
// 收到通知后在日志中记录一条消息
class LogOpenListener implements EventListener {
    private log: string;

    constructor(fileName: string) {
        this.log = fileName;
    }

    update(eventType: string, file: string): void {
        console.log(`Save to log ${this.log}: Someone has performed ${eventType} operation with the following file: ${file}`);
    }
}

// EventManager.ts
// 基础发布者
class EventManager {
    private listeners: Map<string, EventListener[]> = new Map();

    constructor(operations: string[]) {
        for (const operation of operations) {
            this.listeners.set(operation, []);
        }
    }

    subscribe(eventType: string, listener: EventListener): void {
        const listeners = this.listeners.get(eventType);
        if (listeners) {
            listeners.push(listener);
        }
    }

    unsubscribe(eventType: string, listener: EventListener): void {
        const listeners = this.listeners.get(eventType);
        if (listeners) {
            const index = listeners.indexOf(listener);
            if (index !== -1) {
                listeners.splice(index, 1);
            }
        }
    }

    notify(eventType: string, file: string): void {
        const listeners = this.listeners.get(eventType);
        if (listeners) {
            for (const listener of listeners) {
                listener.update(eventType, file);
            }
        }
    }
}

// Editor.ts
// 具体发布者，由其他对象追踪
class Editor {
     events: EventManager;
     file: string;

    constructor() {
        this.events = new EventManager(["open", "save"]);
    }

    openFile(filePath: string): void {
        this.file = `文件名:${filePath}`;
        this.events.notify("open", this.file);
    }

    saveFile(): void {
        if (this.file) {
            this.events.notify("save", this.file);
        } else {
            console.error("Please open a file first.");
        }
    }
}

// Demo.ts
// 初始化代码
const editor = new Editor();
editor.events.subscribe("open", new LogOpenListener("/path/to/log/file.txt"));
editor.events.subscribe("save", new EmailNotificationListener("admin@sse.com"));

editor.openFile("test.txt");
editor.saveFile();